from django.contrib import auth
from django.http import HttpResponse
from django.shortcuts import render
from openpyxl.writer.excel import ExcelWriter
from rest_framework.permissions import IsAuthenticated
from rest_framework.viewsets import ViewSet
from rest_framework.decorators import action
from rest_framework.viewsets import ModelViewSet
# from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from . import serializer
from studentSystemt.utils.response import ApiResponse
from . import models
from . import authen
import time
from rest_framework.viewsets import ViewSetMixin
import json
from rest_framework.viewsets import GenericViewSet
from rest_framework.mixins import ListModelMixin,CreateModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin
# from rest_framework.generics import ListAPIView,DestroyAPIView,UpdateAPIView,RetrieveAPIView,CreateAPIView
from django.db.models import Q,F
# from rest_framework.generics import GenericAPIView
from rest_framework.views import APIView
from django.conf import settings
#导入异步框架的任务,异步发送验证码邮件
# from script.celery_task.emailtask import send_email as celey_send_email
from django.core.cache import cache
# from script.celery_task import task2
#存放缓存的keys
from studentSystemt.settings import othersettings
from openpyxl import Workbook
import os
from  .authen import MyJWTAuthentication


#获取token
def _get_token(user):
    from rest_framework_jwt.serializers import jwt_payload_handler, jwt_encode_handler
    #传递用户对象，获取token
    payload = jwt_payload_handler(user)
    token = jwt_encode_handler(payload)
    return token
#拿到redis的连接
def get_redis():
    from studentSystemt.utils.redis_con import POOL
    import redis
    r = redis.Redis(connection_pool=POOL,decode_responses=True)
    return r
#拿到当前时间的学期
def get_semester():
    # 拿到当前时间年
    thetime = time.localtime().tm_year
    # 拿到当前时间的月份
    month = int(time.localtime().tm_mon)
    # thetime=2022
    # month=3
    thetime0 = int(thetime) - 1
    lis01 = [9, 10, 11, 12, 1, 2]  # 录入分数可能的时间,2019-2020第一学期
    list02 = [3, 4, 5, 6, 7, 8]  # 录入分数可能的时间    ,2019-2020第二学期
    if month in lis01:
        thetime = str(thetime0 + 1) + '-' + str(thetime0 + 2) + '第一学期'
        if month == 1 or month == 2:
            thetime = str(thetime0) + '-' + str(thetime0 + 1) + '第一学期'
            # 如果在1，2月份操作，还是在第一学期，但是年份已经过一年，所以要减
    elif month in list02:
        thetime = str(thetime0) + '-' + str(thetime0 + 1) + '第二学期'
    return thetime
#生成验证码
def email_code(count=5):
    import random
    lis = []
    for i in range(count):
        code = random.randint(0, 9)
        lis.append(str(code))
    return ''.join(lis)
#同步发送验证码邮件
def send_email(recv,code,sender="13510391274@163.com", passward='IMJBAXPFAUJSXSUZ'):
    from studentSystemt.utils import email
    email_obj = email.Send_mail(sender=sender, passward=passward, receivers=recv)
    name = '路飞学城'
    text = f'您的验证码是:{code}'
    head = '路飞学城验证码：若非本人操作，请忽略此消息！！'
    #'IMJBAXPFAUJSXSUZ'
    email_obj.send(Name=name, ShowText=text, Header_show=head)
    return True
#用户登录的view
class UserView(ViewSet):
    #登录不需要认证
    authentication_classes = []
    #datail=True的时候，查询字符串携带pk
    @action(methods=['POST',],detail=False)
    def login(self,request,*args,**kwargs):
        username = request.data.get('username')
        password = request.data.get('password')
        try:
            #用户存在，则一定能拿到用户对象
            user = models.User.objects.get(username=username)
            ret = user.check_password(password)
        except Exception as e:
            return ApiResponse(msg='登录失败',code=104,data={'errors':'用户不存在'})
        # ret = auth.authenticate(request,**request.data)
        if ret:
            token = _get_token(user)
            return  ApiResponse(msg='登录成功',code=100,role=user.role,data={'token':token,'username':username})
        else:
            return ApiResponse(msg='用户名或密码错误',code=101)

from .pagination import PageNumberPaginations #导入重写的分页器类
class StudentClassView(GenericViewSet,ListModelMixin):
    queryset = models.User.objects.filter(role=4)
    serializer_class = serializer.StudentsSerializer
    pagination_class = PageNumberPaginations
    #重写ListModelMixin类中的list方法
    def list(self, request, *args, **kwargs):
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role!=4:
            return ApiResponse(code=104,msg='学生才能操作')
        #拿到指定的数据对象，下面的代码就使用原生的即可
        queryset = models.User.objects.filter(stuclass=user.stuclass,role=4)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(serializer.data)

    # def list(self, request, *args, **kwargs):
    #     user_id = request.auth.get('id')
    #     user = models.User.objects.get(id=user_id)
    #     if user.role==4:
    #         stuclass = user.stuclass
    #         # #分页的数据对象
    #         students = models.User.objects.filter(stuclass=stuclass,role=4)
    #         # #分页器对象
    #         pages= PageNumberPaginations()
    #         # #生成数据
    #         # page_list = page.paginate_queryset(students,request,view=self)
    #         # ser = serializer.StudentsSerializer(instance=page_list,many=True)
    #         dic=(request,students,self)
    #         response = pages.get_paginated_response(*dic)
    #         return ApiResponse(data=response)
    #     return ApiResponse(code=104,msg='不是学生无法操作')




#学生的功能
class StudentHomeView(ViewSet):
    authentication_classes = [authen.MyJWTAuthentication]
    # 展示同班同学的信息
    @action(methods=['GET'],detail=False)
    def showclass(self,request):
        username= request.user
        user_obj = models.User.objects.filter(username=username).first()
        #拿到当前用户的班级的id
        stu_class_id=user_obj.stuclass_id
        #拿到当前登录的用户对象,查询同班的人且是学生
        class_all_stu = models.User.objects.filter(stuclass_id=stu_class_id,role=4)
        #对同班同学进行序列化操作
        ser = serializer.StudentsSerializer(instance=class_all_stu,many=True)
        return ApiResponse(data=ser.data)
    #查看课程具体上课情况
    @action(methods=['get'],detail=False)
    def showmycourse(self,request,*args,**kwargs):
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        semestername = get_semester()
        if user.role==4:
            stuclass = user.stuclass
            try:
                curi = models.Curriculum.objects.filter(stuclass=stuclass,semester__semestername=semestername)
                ser = serializer.ShowCurriSerializer(instance=curi,many=True)
                choicecourse = models.ChoiceCourseStudy.objects.filter(course__studentchoicecourse__student_id=request.auth.get('id'),course__semster__semestername=get_semester())
                ser_choice = serializer.StuChoiceCourseView(instance=choicecourse,many=True)
                return ApiResponse(data={'object':ser.data,'choice':ser_choice.data})
            except Exception as e:
                return ApiResponse(code=104,msg='携带数据错误',error=str(e))
        elif user.role==3:#老师专业班级的课程
            profession = models.TeaProfession.objects.get(teacher=user)
            curi = models.Curriculum.objects.filter(stuclass__profession_id=profession.id,semester__semestername=semestername,teacher=user)
            ser = serializer.ShowCurriSerializer(instance=curi,many=True)
            choicecourse = models.ChoiceCourseStudy.objects.filter(
                course__teacher_id=request.auth.get('id'),
                course__semster__semestername=get_semester())
            ser_choice = serializer.StuChoiceCourseView(instance=choicecourse, many=True)

            return ApiResponse(data={'object':ser.data,'choice':ser_choice.data})
    #个人信息展示
    @action(methods=['GET'], detail=False)
    def showmyself(self,request):
        user = models.User.objects.filter(username=request.user).first()
        ser = serializer.StudentsSerializer(instance=user)
        return ApiResponse(msg='查询成功',data=ser.data)
    #展示班导师信息
    @action(methods=['GET'], detail=False)
    def showteacher(self,request):
        user = models.User.objects.filter(username=request.user).first()
        class_id = user.stuclass
        #拿到老师与班级的对应关系的数据对象
        obj = models.Class2Teacher.objects.filter(stuclass_id=class_id).first()
        if obj:
            teacher = obj.teacher
            ser = serializer.StudentsSerializer(instance=teacher)
            return ApiResponse(msg='查询成功', data=ser.data)
        return ApiResponse(msg='查询失败',code=102,data={'errors':'找不到对应的班导师'})
    #修改密码
    @action(methods=['POST'], detail=False)
    def stupassword(self,request):
        ser = serializer.StuPasswordSerializer(data=request.data,context={'request':request})
        if ser.is_valid():
            try:
                user = models.User.objects.filter(username=request.data.get('username')).first()
                password = request.data.get('password')
                user.set_password(password)
                user.save()
                return ApiResponse(msg='修改密码成功',data={'username':request.user})
            except Exception as e:
                return ApiResponse(msg='修改密码失败',data={'errors':e})
        return ApiResponse(msg='修改密码失败',data={'errors':ser.errors},code=102)
    #展示某学期的课程分数
    @action(methods=['GET'], detail=False)
    def showcredit(self,request):
        #经过认证组件后，可以通过request.user获取到元组的第一个元素，
        #通过request.auth 获取到元组的第二个元素
        semester_id = request.query_params.get('pk')
        username = request.user
        if username[:3]=='312':
            #拿到用户选择要查看的学期的id
            try:
                if not semester_id:
                    return ApiResponse(code=104,msg='查询失败，未传递学期id')
                user_id = request.auth.get('id')
                #拿到专业
                profession = models.Profession.objects.filter(stuclass__user=user_id).first()
                #一个专业在一个学期的必修课程是一样的。
                stu_core = models.Election.objects.filter(student_id=user_id,course__profession=profession,course__semester=semester_id)
                ser = serializer.StuCreditSerializer(instance=stu_core,many=True)
                return ApiResponse(msg='查询成功',data={
                    'result':ser.data
                })
            except Exception as e:
                return ApiResponse(code=104,msg='数据库查询失败',data={'errors':e})
        else:
            return ApiResponse(msg='查询失败',code=104,data={
                'result':'查询成绩，只能学生进行操作'
            })
    #查看考试信息
    @action(methods=['GET'],detail=False)
    def showkaoshi(self,request,*args,**kwargs):
        semester_id = request.query_params.get('semester_id')
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role != 4:
            return ApiResponse(code=104,msg='该操作只能学生进行')
        try:
            semester = models.Semester.objects.get(id=semester_id)
        except:
            return ApiResponse(code=104,msg='传递的学期有误。')
        exam = models.Unifiedcourse.objects.filter(status=3,stuclass__user=user,course__semester_id=semester_id)
        ser = serializer.UnifileExamSerializer(instance=exam,many=True)
        return ApiResponse(data=ser.data)






'''
管理员功能
'''

#管理员的功能
class AdminView(ViewSet):
    authentication_classes = [authen.MyJWTAuthentication]
    #创建单个用户
    @action(methods=['POST'], detail=False)
    def createuser(self,request):
        #反序列化
        ser = serializer.CreateUser(data=request.data,context={'request':request})
        if ser.is_valid():
            try:
                user = models.User.objects.create_user(**request.data)
                user.save()
                return ApiResponse(msg='创建用户成功',data={'user':request.data.get('username')})
            except Exception as e:
                return ApiResponse(code=114,msg='创建失败，存在非法字段',data={'errors':e})

        return ApiResponse(code=104,msg='创建用户失败',data={
            'errors':ser.errors
        })
    #上传批量创建用户文件
    @action(methods=['POST'], detail=False)
    def adminfile(self,request,*args,**kwargs):
        ser = serializer.AdminFileSerializer(data=request.data,context={'request':request})
        if ser.is_valid():
            try:#认证模块authentic中成功是返回（username,{'id':'user_id,'token':token}）
                #form-data到后端的格式不一样了
                file = models.AdminFile.objects.create(filename=request.data.get('filename'),file=request.data.get('file'),desc=request.data.get('desc'),user_id=request.auth.get('id'))
                return ApiResponse(msg='上传文件成功', data={'filename': request.data.get('filename')})
            except Exception as e:
                return ApiResponse(msg='上传文件失败',code=104,data={'errors':e})
        return ApiResponse(msg='文件上传失败',code='104',data={'erroes':ser.errors})
    #将管理员上传的批量文件展示出来
    @action(methods=['GET'], detail=False)
    def showadminfile(self,request,*args,**kwargs):
        #需要登录的api，经过认证后都可以在 request.user和request.auth中拿到元组第一个和第二个元素
        username = request.user
        user = models.User.objects.get(id = request.auth.get('id'))
        if user.role in [1,2]:
            file = models.AdminFile.objects.filter(user_id=request.auth.get('id'))
            if file:
                ser = serializer.AdminFileSerializer(instance=file,many=True)
                return ApiResponse(msg='文件展示成功',data={'date':ser.data})
            return ApiResponse(msg='管理员未上传文件',code=104)
        else:
            return ApiResponse(msg='非管理员无法操作',code=103)
    #点击批量注册文件，执行批量注册功能
    @action(methods=['GET'], detail=True)
    def registermany(self,request,*args,**kwargs):
        #获取到文件的id，对批量注册文件进行操作
        pk = kwargs.get('pk')
        user = models.User.objects.get(id=request.auth.get('id'))
        try:
            fileobj = models.AdminFile.objects.get(pk=pk)
        except:
            return ApiResponse(code=104,msg='文件id找不到')
        #拿到文件存放的路径
        file  = fileobj.file
        success = []
        failure = []
        if user.role not in [1,2]:
            return ApiResponse(msg='没有权限',code=103,data={'errors':'只有管理员才能操作'})
        for i,line in enumerate(file):
            if i==0:
                #拿到标题的上的变量名
                try:
                    key_list = line.decode('utf-8').strip().split('|')
                except:
                    key_list = line.decode('gbk').strip().split('|')

            else:
                #拿到所有数据
                try:
                    value_list = line.decode('utf-8').strip().split('|')
                except:
                    value_list = line.decode('utf-8').strip().split('|')
                try:
                    #字典生成器
                    dic={key_list[index]:value_list[index] for index in range(len(value_list))}
                except Exception as e:
                    value_list.append(str(e))
                    failure.append(value_list)
                    continue
                try:
                    stuclass = models.stuClass.objects.get(classon=dic['stuclass'])

                except Exception as e:
                    value_list.append(str(e))
                    failure.append(value_list)
                    continue
                dic['stuclass']=stuclass
                #判断用户名是否正确
                username = dic.get('username')
                if  (username[:3]=='312' or username[:3]=='512') and len(username)==8:
                    try:
                        #将一条数据进行写入
                        models.User.objects.create_user(**dic)
                        success.append(value_list)
                        #将是否使用过设置成true
                        fileobj.is_used=True
                        fileobj.save()
                    except Exception as e:
                        #若失败，写入到失败字典中
                        value_list.append(str(e))
                        failure.append(value_list)
                else:
                    failure.append(value_list)
        return ApiResponse(msg='批量注册用户执行',data={
            'success':success,
            'failure':failure
        })
    #一条一条录入奖学金情况
    @action(methods=['POST'],detail=False)
    def simpleprizes(self,request,*args,**kwargs):
        ser = serializer.PrizeSerializer(data=request.data)
        if ser.is_valid():
            return ApiResponse(data=ser.data)
        else:
            return ApiResponse(code=104,msg='录入奖学金失败',data={'error':ser.errors})
    #上传奖学金excel文件
    @action(methods=['POST'],detail=False)
    def prizefile(self,request,*args,**kwargs):
        user = models.User.objects.get(id=request.auth.get('id'))
        file = request.data.get('file')
        filetype = file.name.split('.')[-1]
        if filetype not in ['xlsx','xls']:
            return ApiResponse(code=104,msg='只能接收xlsx和xls格式文件')
        if user.role not in [1,2]:
            return ApiResponse(code=104,msg='没有权限操作')
        try:
            models.PrizeFile.objects.create(user=user,name=request.data.get('name'),desc=request.data.get('desc'),file=request.data.get('file'))
            return ApiResponse(msg='文件上传成功',data={
                'filename':request.data.get("name"),
                'desc':request.data.get('desc')
            })
        except Exception as e:
            return ApiResponse(code=104,msg='上传文件失败',data=str(e))
    #查看上传奖学金的excel文件
    @action(methods=['GET'],detail=False)
    def showprizefile(self,request,*args,**kwargs):
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role not in [1,2]:
            return ApiResponse(code=104,msg='没有权限操作')
        files=models.PrizeFile.objects.filter(user_id=request.auth.get('id'),is_deleted=False)
        ser = serializer.PrizeFileSerializer(instance=files,many=True)
        return ApiResponse(data=ser.data)
    #读取奖学金excel文件，批量写入数据库中
    @action(methods=['get'],detail=False)
    def writeprizefile(self,request,*args,**kwargs):
        '''
        批量读取excel文件的内容，写到数据库中
        :param pk= prizefile表的id:
        :param args:
        :param kwargs:
        :return:
        '''
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role not in [1,2]:
            return ApiResponse(code=104,msg='没有权限操作')
        file_id= request.query_params.get('pk')
        try:
            file=models.PrizeFile.objects.get(id=file_id)
            #代表文件已经被操作了
            file.is_used=True
            file.save()
        except:
            return ApiResponse(code=104,msg='找到文件数据，携带的数据错误')
        path = os.path.join(settings.MEDIA_ROOT,file.file.name)
        wb = openpyxl.load_workbook(path)
        ws = wb.active
        max_row = ws.max_row
        max_column = ws.max_column
        success=[]
        faild = []
        title = []
        for row in range(1,max_row+1):
            dic={}
            if row==1:
                for column in range(1, max_column + 1):
                    title.append(ws.cell(row=row, column=column).value)
                continue
            for column in range(1,max_column+1):
                dic[title[column-1]]= ws.cell(row=row,column=column).value
            try:

                prize=models.Prize.objects.get_or_create(
                    student=models.User.objects.get(username=dic['student']),
                    level=dic['level'],
                    semester=models.Semester.objects.get(semestername=dic['semester']),
                    allcourse=dic['allcourse'],
                    stuclass=models.stuClass.objects.get(classon=dic['stuclass']),
                    college=models.College.objects.get(collegename=dic['college']),
                    profession=models.Profession.objects.get(pname=dic['profession'])
                )
                # 创建成功的返回值是一个对
                # if prize==dic['student']:
                #     success.append(dic)
                # else:
                #     dic['错误']='记录已经存在了'
                #     faild.append(dic
                success.append(dic)
            except Exception as e:
                dic['错误原因']=str(e)
                faild.append(dic)
        return ApiResponse(data={
            'success':success,
            'faild':faild
        })
    #管理员查看奖学金情况
    @action(methods=['get'],detail=False)
    def semesterprize(self,request,*args,**kwargs):
        '''
        :param request:
        通过前端传递过来的学期的id和学院的id，获取对应的奖学金情况
        :return:
        '''
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role not in [1,2]:
            return ApiResponse(code=104,msg='没有权限操作这个')
        semester_id=request.query_params.get("semester_id")
        college_id=request.query_params.get('college_id')
        if not semester_id or not college_id:
            return ApiResponse(code=104,msg='少携带了部分数据')
        prizes = models.Prize.objects.filter(semester_id=semester_id,college_id=college_id).order_by('level')
        ser = serializer.PrizeSerializer(instance=prizes,many=True)
        return ApiResponse(data=ser.data)
    #申请失败原因
    @action(methods=['post'], detail=True)
    def examfailse(self,request,*args,**kwargs):
        unifile_id = request.data.get('pk')
        result = request.data.get('result')
        try:
            unifile = models.Unifiedcourse.objects.filter(id=unifile_id,available=False)
            if unifile:
                examfailse = models.ExamFaile.objects.create(unifile_id=unifile_id,why=request)
            else:
                return ApiResponse(code=104,msg='操作的申请已经通过，不能操作')
        except:
            pass
#实现对应奖学金记录进行删除
class AmdinPrizeDelChange(GenericViewSet,DestroyModelMixin):
    queryset = models.Prize.objects.all()
    serializer_class = serializer.PrizeSerializer
    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, *args, **kwargs)
        return ApiResponse(msg='删除记录成功')

#管理员查看需要审核的申请，进行审核
class AdminExamView(GenericViewSet,ListModelMixin,UpdateModelMixin):
    authentication_classes = [authen.MyJWTAuthentication]
    queryset = models.Unifiedcourse.objects.filter(status=1)
    serializer_class = serializer.UnifileExamSerializer
    #修改考试申请的状态,审核通过、审核不通过
    def update(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        pk = kwargs.get('pk')
        status = request.data.get('status')
        relust = request.data.get('relust','')
        if status not in [2,3]:
            return ApiResponse(code=104,msg='审批对应的数字有问题')
        try:
            user = models.User.objects.get(id=user_id)
            if user.role in [1,2,3]:
                exam = models.Unifiedcourse.objects.get(id=pk)
                exam.status=status
                exam.relust=relust
                exam.save()
                return ApiResponse(msg='修改成功',data={'status':exam.get_status_display(),'course':exam.course.coursename,'teacher':exam.teacher.username})
            else:
                return ApiResponse(code=104,msg='没有权限')
        except:
            return ApiResponse(code=104,msg='携带的数据错误')
#管理员查看已经审批通过的考试申请
class AdminExamViewT(GenericViewSet,ListModelMixin):
    queryset = models.Unifiedcourse.objects.filter(status=3)
    serializer_class = serializer.UnifileExamSerializer
#管理员查看所有审核不通过的申请
class AdminExamViewF(GenericViewSet,ListModelMixin):
    queryset = models.Unifiedcourse.objects.filter(status=2)
    serializer_class = serializer.UnifileExamSerializer
#管理员创建班级、专业、学院
class AdminCreateCPC(ViewSetMixin,APIView):
    #创建班级
    @action(methods=['post'],detail=False)
    def creclass(self,request,*args,**kwargs):
        ser = serializer.ClassSerializer(data=request.data)
        if ser.is_valid():
            models.stuClass.objects.create(classon=request.data.get('classon'), profession_id=request.data.get('profession'))
            return ApiResponse(data={'result':ser.data})
        return ApiResponse(code=104,msg='操作失败',data={'error':ser.errors})
    #创建专业
    @action(methods=['post'], detail=False)
    def creprofession(self,request,*args,**kwargs):
        ser = serializer.ProfessionSerializer(data=request.data)
        if ser.is_valid():
            return ApiResponse(msg='创建专业成功',data=ser.data)
        return ApiResponse(code=104,msg='创建失败',data={'errors':ser.errors})
    #创建学院
    @action(methods=['post'], detail=False)
    def crecollege(self,request,*args,**kwargs):
        ser = serializer.CollegeSerializer(data=request.data)
        if ser.is_valid():
            return ApiResponse(msg='创建学院成功',data=request.data)
        return ApiResponse(msg='创建学院失败',code=104,data=ser.errors)

# 管理员查看学院
class ShowCollege(GenericViewSet,ListModelMixin):
    queryset = models.College.objects.all()
    serializer_class = serializer.CollegeSerializer
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        return ApiResponse(data=response.data)
# 管理员查看班级
class ShowClass(GenericViewSet,ListModelMixin):
    queryset = models.stuClass.objects.all()
    serializer_class = serializer.ClassSerializer
    def list(self, request, *args, **kwargs):
        response = super().list(request, *args, **kwargs)
        return ApiResponse(data=response.data)
#管理员查看专业
class ShowProfession(GenericViewSet,ListModelMixin):
    queryset = models.Profession.objects.all()
    serializer_class = serializer.ProfessionSerializer
    def list(self, request, *args, **kwargs): #【将内容缓存到redis中】
        redis_profession = cache.get('redis_profession')
        if redis_profession:
            print('409，使用缓存')
            return ApiResponse(data=redis_profession)
        response = super().list(request, *args, **kwargs)
        #将专业信息缓存到redis数据库中
        cache.set('redis_profession',response.data)
        return ApiResponse(data=response.data)

#学期的增删改查
class SemesterView(ModelViewSet):
    queryset = models.Semester.objects.all()
    serializer_class = serializer.SemesterSerializer
    def create(self, request, *args, **kwargs):
        pk = request.auth.get('id')
        user = models.User.objects.filter(id=pk).first()
        if user.role in [1,2]:
            semestername=request.data.get('semestername')
            semester = models.Semester.objects.filter(semestername=semestername)
            if not semester:
                models.Semester.objects.create(semestername=semestername)
                return ApiResponse(data={'semester':semestername})
            return ApiResponse(code=104,msg='学期已经存在了')
        return ApiResponse(code=104,msg='没有权限操作')
    def destroy(self, request, *args, **kwargs):
        return ApiResponse(code=104,msg='暂时不支持该操作')
    def update(self, request, *args, **kwargs):
        semester_id = kwargs.get('pk')
        pk = request.auth.get('id')
        user = models.User.objects.filter(id=pk).first()
        if user.role in [1,2]:
            try:
                semester=models.Semester.objects.get(id=semester_id)
                semester.semestername=request.data.get('semestername')
                semester.save()
                return ApiResponse(data={'semester':request.data.get('semestername')})
            except:
                return ApiResponse(code=104,msg='携带的数据存在问题')
        return ApiResponse(code=104,msg='没有权限操作')
#公告的增删改查
class SchoolMessegeView(ModelViewSet):
    queryset = models.SchoolMessege.objects.all()
    serializer_class = serializer.MessegeSerializer
    def destroy(self, request, *args, **kwargs):
        pk = kwargs.get('pk')
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role not in [1,2,3]:
            return ApiResponse(code=104,msg='没有权限操作')
        try:
            messege=models.SchoolMessege.objects.get(id=pk)
            title = messege.title
            messege.delete()
            messege.save()
            return ApiResponse(msg='删除成功',data={'title':title})
        except:
            return ApiResponse(code=104,msg='没有此数据')
    def list(self, request, *args, **kwargs):#将数据缓存到redis中

        redis_message = cache.get('redis_messege_all')
        if redis_message:
            # 从缓存中能取出公告数据就直接返回
            print('493使用缓存')
            return ApiResponse(data=redis_message)
        #从缓存中没有取到,就直接执行list方法,从数据库中取,并将数据缓存到redis中
        response = super().list(request, *args, **kwargs)
        cache.set('redis_messege_all',response.data)
        print('493使用数据库')
        return ApiResponse(data=response.data)
    def create(self, request, *args, **kwargs):
        response = super().create(request, *args, **kwargs)
        response2 = super().list(request, *args, **kwargs)
        cache.set('redis_messege_all',response2.data)
        return ApiResponse(data=response.data)


#管理员获取到院系与专业的数据
#获取专业的老师、班级、课程的数据
class AdminGetMesView(ViewSet):
    #拿到学院与专业的对应数据{'智能制造学院':[{专业id:,name:通信工程，学院id:1},{}]}
    @action(methods=['get'],detail=False)
    def showcollpro(self,request,*args,**kwargs):
        user_id=request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role !=1 or user.role!=2:#只有管理员才能操作
            return ApiResponse(code=102,msg='没有权限')
        college = models.College.objects.all()
        lis=[]
        for co in college:
            profession = models.Profession.objects.filter(college=co)
            ser = serializer.ProfessionSerializer(instance=profession,many=True)
            lis.append({co.collegename:ser.data})
        return ApiResponse(date=lis)
    #获取班级、课程、老师,通过前端传递过来的专业id
    @action(methods=['get'],detail=False)
    def showcct(self,request,*args,**kwargs):
        profession_id = request.query_params.get('pk')
        if not  profession_id:
            return ApiResponse(code=104,msg='查询失败',data={'error':'没有携带专业id'})
        try:
            models.Profession.objects.get(id=profession_id)
        except:
            return ApiResponse(code=102,msg='查询失败',data={'error':'携带的专业id查询不到'})

        stuclass=models.stuClass.objects.filter(profession_id=profession_id)
        teacher = models.TeaProfession.objects.filter(profession_id=profession_id)
        #拿到当前学期对应的学期名
        semestername = get_semester()
        semester = models.Semester.objects.get(semestername=semestername)
        course = models.Course.objects.filter(semester__semestername=semestername,profession_id=profession_id)
        ser_calss = serializer.ClassSerializer(instance=stuclass,many=True)
        ser_course = serializer.CourseSerializer(instance=course,many=True)
        ser_teacher = serializer.TeacherSerializer(instance=teacher,many=True)
        ser_semester = serializer.SemesterSerializer(instance=semester)
        return ApiResponse(data={
            'course':ser_course.data,
            'teacher':ser_teacher.data,
            'class':ser_calss.data,
            'semester':ser_semester.data
        })
    #创建课程信息情况
    @action(methods=['POST'],detail=False)
    def credetailcourse(self,request,*args,**kwargs):
        ser = serializer.CurricuSerializer(data=request.data)
        if ser.is_valid():
            return ApiResponse(data={'result':ser.data})
        return ApiResponse(code=104,msg=ser.errors)
    #查看课程详情
    @action(methods=['get'], detail=False)
    def showdetailcou(self,request,*args,**kwargs):
        profession_id = request.query_params.get('pk')
        #获取当前学期的信息
        semester = get_semester()
        lis=[]
        try:
            profession = models.Profession.objects.get(id=profession_id)
            cour = models.Curriculum.objects.filter(course__profession_id=profession_id,course__semester__semestername=semester)
            ser = serializer.ShowCurriSerializer(instance=cour,many=True)
            return ApiResponse(data=ser.data)
        except:
            return ApiResponse(code=104,msg='找不到相关的数据')

        # try:
        #     course = models.Course.objects.filter(profession_id=profession_id,semester__semestername=semester)
        #
        #     for cou in course:
        #         curricu = models.Curriculum.objects.filter(course=cou).order_by('stuclass')
        #         ser = serializer.ShowCurriSerializer(instance=curricu,many=True)
        #         # lis.append({'coursename':cou.coursename,'lable':ser.data})
        #         lis.append(ser.data)
        #     return ApiResponse(data=lis)
        # except:
        #     return ApiResponse(code=104,msg='查询失败')




class AdminStuclassView(ViewSet):
    #拿到学院-专业-班级的对应关系
    @action(methods=['get'],detail=False)
    def professionclass(self,request,*args,**kwargs):
        user = models.User.objects.get(id=request.auth.get('id'))
        lis=[]#使用列表的装
        if user.role in [1,2,3]:
            college = models.College.objects.all()
            #拿到所有的学院
            for col in college:
                #拿到学院对应的所有专业
                profession  = models.Profession.objects.filter(college=col)
                ser_pro = serializer.ProfessionSerializer(instance=profession,many=True)
                flag=True
                for pro in profession:
                    stuclass=models.stuClass.objects.filter(profession=pro)
                    ser_class = serializer.ClassSerializer(instance=stuclass,many=True)
                    if flag:
                        dic={'college_id':col.id,'lable':col.collegename,'children':[{'profession_id':pro.id, 'label':pro.pname,'children':ser_class.data}]}
                        flag=False
                        continue
                    dic['children'].append({'profession_id':pro.id, pro.pname:ser_class.data})
                    #循环遍历，每次拿到一条学院、专业、班级的对应关系，添加到列表中
                    lis.append(dic)
            semester =models.Semester.objects.all()
            ser_seme = serializer.SemesterSerializer(instance=semester,many=True)
            return ApiResponse(semester=ser_seme.data,data=lis)
        return ApiResponse(code=104,msg='非管理员无操作')

class AdminStuCreditView(GenericViewSet,ListModelMixin):
    serializer_class = serializer.StuCreditSerializer
    queryset = models.Election.objects.all()
    pagination_class = PageNumberPaginations
    #重写list方法：拿到某个班级所有学生的所有课程的情况
    def list(self, request, *args, **kwargs):
        stuclass_id = request.query_params.get('stuclass_id')
        user = models.User.objects.get(id=request.auth.get('id'))
        semester_id = request.query_params.get('semester_id')
        if not semester_id or not stuclass_id:
            return ApiResponse(code=104, msg='没有携带学期id和班级id')
        if user.role not in [1, 2, 3]:
            return ApiResponse(code=104,msg='没有权限')
        queryset =models.Election.objects.filter(stuclass_id=stuclass_id, course__semester_id=semester_id).order_by(
            'student')
        #上面是重写代码的部门
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(serializer.data)


    # @action(methods=['get'], detail=False)
    # def studentsscore(self, request, *args, **kwargs):
    #     stuclass_id = request.query_params.get('stuclass_id')
    #     user = models.User.objects.get(id=request.auth.get('id'))
    #     semester_id = request.query_params.get('semester_id')
    #     if not semester_id or not stuclass_id:
    #         return ApiResponse(code=104,msg='没有携带学期id和班级id')
    #     if user.role in [1,2,3]:
    #         score = models.Election.objects.filter(stuclass_id=stuclass_id,course__semester_id=semester_id).order_by('student')
    #         ser =serializer.StuCreditSerializer(instance=score,many=True)
    #         return ApiResponse(data=ser.data)
    #     return ApiResponse(code=104,msg='没有权限')
from django_filters.rest_framework import DjangoFilterBackend
#老师管理员实现搜索功能，通过姓名、学号、班级查找学生
class AmindSearchStudentView(GenericViewSet,ListModelMixin):
    queryset = models.User.objects.all()
    serializer_class = serializer.StudentsSerializer
    pagination_class = PageNumberPaginations
    def list(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role not in[1,2,3]:
            return ApiResponse(code=104,msg='非管理员无权限操作')
        search = request.query_params.get('search')
        queryset = models.User.objects.filter(Q(name__icontains=search)|Q(username__icontains=search)|Q(stuclass__classon__icontains=search))
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(serializer.data)


''' 老师的功能  '''
#老师查看
class TeacherView(ViewSet):
    #查看具体学期下某个班级的学生的成绩
    @action(methods=['get'],detail=False)
    def showstudent(self,request,*args,**kwargs):
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role==4:
            return ApiResponse(code=104,msg='没有权限操作')
        #拿到班级id、拿到学期id
        semester_pk = request.query_params.get('s_pk')
        class_pk = request.query_params.get('c_pk')
        if semester_pk and class_pk:
            #给班级所有学生创建对应课程的成绩记录
            students = models.User.objects.filter(stuclass_id=class_pk,role=4)
            profession = models.TeaProfession.objects.filter(teacher_id=user_id).first()
            courses = models.Course.objects.filter(profession_id=profession.id,semester_id=semester_pk)
            for course in courses:
                for student in students:
                    models.Election.objects.get_or_create(course_id=course.id, student_id=student.id, stuclass_id=class_pk)
            #拿到学生的分数
            stu_credit = models.Election.objects.filter(stuclass_id=class_pk,course__semester=semester_pk).order_by('student_id')
            if stu_credit:
                ser = serializer.StuCreditSerializer(instance=stu_credit,many=True)
                courses = models.Course.objects.filter(semester_id=semester_pk,profession__stuclass=class_pk)
                c_ser = serializer.CourseSerializer(instance=courses,many=True)
                return ApiResponse(course =c_ser.data,data=ser.data)
            return ApiResponse(code=104,msg='查不到数据')
        return ApiResponse(code=104,msg='失败',data={'errors':'没有携带学期s_pk或班级c_pk'})
    #修改某个学生的成绩
    @action(methods=['get'],detail=False)
    def editelection(self,request,*args,**kwargs):
        #课程分数表的id
        election_id  = request.query_params.get('pk')
        score = request.query_params.get('score')
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        #如果是学生则无权限操作
        if user.role==4:
            return ApiResponse(code=104,msg='无权限操作')
        #拿到学生课程成绩的记录的id值和修改后的分数
        try:
            ele =models.Election.objects.get(id=election_id)
            ele.score=score
            if float(score)<60:#分数低于60分，is_pass设置为false
                ele.is_pass=False
            ele.save()
            return ApiResponse(data={'username':ele.student.username,'courese':ele.course.coursename,'score':score})
        except:
            return ApiResponse(code=104,msg='请求失败',data={'error':'传递的数据存在问题'})
    #获取老师所在专业的当前学期、班级、课程
    @action(methods=['get'], detail=False)
    def foraddele(self, request, *args, **kwargs):
        teacher_id = request.auth.get('id')
        user = models.User.objects.get(id=teacher_id)
        #设置学生没有权限操作
        if user.role==5:
            return ApiResponse(code=104,msg='没有权限操作')
        thetime = get_semester()
        # 拿到老师对应专业的班级。
        profession = models.TeaProfession.objects.filter(teacher_id=teacher_id).first()
        # 拿到专业对应的班级
        stuclass = models.stuClass.objects.filter(profession_id=profession.id)
        ser_class = serializer.ClassSerializer(instance=stuclass, many=True)
        #拿到当前时间的两个学期。
        semester = models.Semester.objects.filter(Q(semestername__startswith=thetime))
        ser_semester = serializer.SemesterSerializer(instance=semester,many=True)
        #第一学期的课程
        course_1 = models.Course.objects.filter(profession_id=profession.id,semester=semester[0])
        #第二学期的课程
        # course_2 = models.Course.objects.filter(profession_id=profession.id, semester=semester[1])
        ser_course1 = serializer.CourseSerializer(instance=course_1,many=True)
        # ser_course2 = serializer.CourseSerializer(instance=course_2,many=True)
        return ApiResponse(data={'semester':ser_semester.data[0],
                          'stuclass': ser_class.data,
                          'course': ser_course1.data})
    #拿到班级所有学生,筛选完成，点击获取学生信息按钮触发该函数，获取班级学生的成绩情况
    @action(methods=['post'],detail=False)
    def clastudent(self,request,*args,**kwargs):
        # request.data={stuclass_id:2,course_id:3}
        stuclass_id = request.data.get('stuclass_id')
        try:
            models.stuClass.objects.get(id=stuclass_id)
            models.Course.objects.get(id=request.data.get('course_id'))

        except:
            return ApiResponse(code=104, msg='无效的班级id或课程id')

        students = models.User.objects.filter(stuclass_id=stuclass_id,role=4).order_by('username')
        score_lis = []
        #给该班级的这个课程的学生，的成绩都创建出来，设置为0
        for stu in students:
           try:
                score=models.Election.objects.get(**request.data,student_id=stu.id)


           except :
                score=models.Election.objects.create(**request.data,student_id=stu.id,score=0,is_pass=False)
           score_lis.append({score.id: {stu.username:score.score,'course':score.course.coursename,'semester':score.course.semester.semestername}})
        return ApiResponse(data=score_lis)
    #录入学生课程成绩,其实到了这里就是修改成绩了，只要拿到成绩的id，分数就可以了
    @action(methods=['get'], detail=False)
    def addelection(self,request,*args,**kwargs):
        election_id = request.query_params.get('pk')
        score = request.query_params.get('score')
        user = models.User.objects.filter(id=request.auth.get('id')).first()
        if user.role==4:
            return ApiResponse(code=104,msg='没有无权进行操作')
        try:
            ele=models.Election.objects.get(id=election_id)
            ele.score=score
            #分数低于60，is_pass=False
            if float(score)<60:
                ele.is_pass=False
            ele.save()
            return ApiResponse(data={'username':ele.student.username,'course':ele.course.coursename,'score':score})
        except :
            return ApiResponse(code=104,msg='不存在的记录')
    #查看老师个人信息
    @action(methods=['get'], detail=False)
    def showteacher(self,request,*args,**kwargs):
        teacher_id = request.auth.get('id')
        try:
            user = models.User.objects.get(id=teacher_id)
            if user.role==3:
                ser = serializer.StudentsSerializer(instance=user)
                return ApiResponse(data={ser.data})
            else:
                return ApiResponse(code=104,msg='没有权限发起操作')
        except:
            return ApiResponse(code=104,msg='传递的数据有误，无法查询')
    #获取老师所在专业的班级信息，专业号
    @action(methods=['get'], detail=False)
    def getclass(self,request,*args,**kwargs):
        teacher_id = request.auth.get('id')
        try:
            user = models.User.objects.get(id=teacher_id)
            if user.role == 3:
                profession = models.TeaProfession.objects.get(teacher_id=teacher_id)
                stuclass = models.stuClass.objects.filter(profession_id=profession.profession)
                ser = serializer.ClassSerializer(instance=stuclass,many=True)
                return ApiResponse(data=ser.data)
            return ApiResponse(code=104,msg='没有权限操作')
        except:
            return ApiResponse(code=104,msg='未知错误')
    #拿到前端传递的班级id和专业id，获取对应班级的学生信息
    @action(methods=['get'], detail=False)
    def teacherclass(self,request,*args,**kwargs):
        teacher_id = request.auth.get('id')
        class_id = request.query_params.get('stuclass_id')
        profession_id = request.query_params.get('profession_id')
        try:
            user = models.User.objects.get(id=teacher_id)
            stuclass = models.stuClass.objects.get(id=class_id)
            if user.role!=4:
                students = models.User.objects.filter(stuclass=stuclass,role=4,stuclass__profession_id=profession_id) #这里可能查不到数据
                ser = serializer.StudentsSerializer(instance=students,many=True)
                return ApiResponse(data=ser.data)
            return ApiResponse(code=104,msg='没有权限操作')
        except:
            return ApiResponse(code=104,msg='传递的数据有误，无法查询到')
    #通过foraddele函数，返回的信息，拿到前端传递的,老师申请考试
    @action(methods=['post'], detail=False)
    def applyexam(self,request,*args,**kwargs):
        stuclass_id=request.data.get('stuclass_id')
        course_id =request.data.get('course_id')
        teacher_id = request.auth.get('id')
        try:
            #检测班级、课程之间是否有联系
            tea = models.User.objects.get(id=teacher_id,role=3)
            profession = models.TeaProfession.objects.get(teacher_id=teacher_id,profession__course=course_id)
            exam = models.Unifiedcourse.objects.filter(stuclass_id=stuclass_id,course_id=course_id).first()
            if exam:
                return ApiResponse(code=104,msg='申请在审核，无须再申请')
            unifile = models.Unifiedcourse.objects.create(**request.data,teacher_id=teacher_id)
            return ApiResponse()
        except:
            return ApiResponse(code=104,msg='没有权限，或携带的数据错误')
        #老师通过学期，获取自己学期所教的课程情况
    @action(methods=['get'],detail=False)
    def teachercourse(self,request,*args,**kwargs):
        semester_id = request.query_params.get('pk')
        user = models.User.objects.get(id=request.auth.get('id'))
        if not semester_id:
            return ApiResponse(code=104,msg='未携带学期id')
        if user.role ==3:
            courese = models.Curriculum.objects.filter(semester_id=semester_id,teacher=user).order_by('course')
            ser = serializer.ShowCurriSerializer(instance=courese,many=True)
            return ApiResponse(data=ser.data)
        return ApiResponse(code=104,msg='只能老师进行操作')


#老师查询班级学生信息，使用分页器分页
class TeacherGetStuclassView(GenericViewSet,ListModelMixin):
    # queryset = models.User.objects.filter(role=4)
    serializer_class = serializer.StudentsSerializer
    pagination_class = PageNumberPaginations #使用重写的分页器
    #重写ListModelMixin的list方法
    def list(self, request, *args, **kwargs):
        stuclass_id = request.query_params.get('stuclass_id')
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if not stuclass_id and user.role!=4 :
            return ApiResponse(code=104,msg='未携带要查询的班级id')
        #获取老师点击的班级的所有数据对象
        queryset = models.User.objects.filter(stuclass_id=stuclass_id,role=4)
        #下面的是源码，除了Reponse改成自己写的ApiResponse
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(serializer.data)


#老师查看自己发起的申请，未审核的
class TeacherExamView(ViewSet):
    queryset = models.Unifiedcourse.objects.all()
    serializer_class = serializer.UnifileExamSerializer
    @action(methods=['get'], detail=False)
    def needexam(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        unifile = self.queryset.filter(teacher_id=user_id, status=1)
        ser = self.serializer_class(instance=unifile, many=True)
        return ApiResponse(data=ser.data, msg='查询待审核的')
    @action(methods=['get'], detail=False)
    def examteapass(self,request,*args,**kwargs):
        user_id = request.auth.get('id')
        unifile = self.queryset.filter(teacher_id=user_id,status=3)
        ser = self.serializer_class(instance=unifile,many=True)
        return ApiResponse(data=ser.data,msg='查询审核通过')
    @action(methods=['get'], detail=False)
    def examunpass(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        unifile = self.queryset.filter(teacher_id=user_id, status=2)
        ser = self.serializer_class(instance=unifile, many=True)
        return ApiResponse(data=ser.data,msg='查询审核不通过')
    @action(methods=['post'], detail=False)
    def examedit(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        try:
            # 拿到申请数据的id
            unifile_id = request.data.pop('pk')
            unifile = self.queryset.filter(teacher_id=user_id, status=2,id=unifile_id)
            if unifile:
                unifile.update(**request.data,status=1,relust='')
                #老师修改后，将会变成未审核的情况
                return ApiResponse(msg='修改申请成功')
            return ApiResponse(msg='只能修改审批不通过',code=104)
        except:
            return ApiResponse(code=104,msg='修改失败')

#公共的，学生或老师或管理员有两个角色都要使用到
class UtilView(ViewSet):
    #所有用户都会使用到的接口
    @action(methods=['get'], detail=False)
    def showsemester(self,request,*args,**kwargs):
        semester = models.Semester.objects.filter(available=True)
        new_semester = models.Semester.objects.get(semestername=get_semester())
        ser = serializer.SemesterSerializer(instance=semester,many=True)
        return ApiResponse(msg='查询学期成功',data={'newsemester':new_semester.id,'result':ser.data})
    @action(methods=['get'], detail=False)
    def showprize(self,request,*args,**kwargs):
        '''
        给老师和学生使用的接口
        :param  拿到学期的id:
        :查询数据：通过学期、学院；查找奖学金的学生
        :return: 用户所在学院下某个学期中获得奖学金的学生
        '''
        semester_id = request.GET.get('pk')
        user_id = request.auth.get('id')
        username = request.user
        if username[:3]=='312':
            profession= models.Profession.objects.filter(stuclass__user=user_id).first()
            college = models.College.objects.filter(profession=profession).first()
        elif username[:3]=='512':
            teaprofession = models.TeaProfession.objects.filter(teacher_id=user_id).first()
            college=teaprofession.profession.college
        else:
            return ApiResponse(msg='查询失败',code=102,data={'result':'请求方式有问题，非法用户'})
        prize = models.Prize.objects.filter(semester_id=semester_id,college=college).order_by('level')
        if prize:
            ser = serializer.PrizeSerializer(instance=prize,many=True)
            return ApiResponse(msg='查询成功',data={'result':ser.data})
        else:
            return ApiResponse(msg='查询失败',code=102,data={'errors':'请求携带数据错误，为找到对应数据'})

'''使用了redis作为验证码缓存的地方'''

class UtilFindPasswordView(ViewSet):
    from django.core.cache import cache
    #找回密码功能，不需要进行认证模块
    authentication_classes = []
    #给用户发送验证码的视图函数
    @action(methods=['post'],detail=False)
    def checkemail(self,request,*args,**kwargs):
        from celery_task import emailtask
        email = request.data.get('email','none')
        username = request.data.get('username')
        try:
            user = models.User.objects.get(**request.data)
            if not user:
                return ApiResponse(code=104,msg='请求失败',data={'error':'邮箱或用户名错误'})
        except:
            return ApiResponse(code=104,msg='请求失败',data={'error':'邮箱或用户名错误'})
        #1 单例模式下生成redis数据库的连接
        redis = get_redis()
        #2 使用django-redis模块,重写cache类实现
        # redis =cache
        #拿到验证码
        code = email_code()
        #1 同步发送邮件
        # send_email(email,code)
        #2 异步发送邮件,函数名.delay(参数)
        emailtask.send_email.delay(recv=email,code=code)
        #将验证码保存到redis数据库中，过期时间是5，EMAILTITLE是key的前缀
        redis.set(settings.EMAILTITLE+username,code,ex=5*60)
        return ApiResponse(msg='验证码发送成功请查收')
    #修改密码的视图函数【暂时注销】
    @action(methods=['post'],detail=False)
    def editpassword(self,request,*args,**kwargs):
        from django.core.cache import cache
        #1 拿到redis数据库连接，传递序列化类
        redis = get_redis()
        #2 使用django-redis实现redis作为缓存
        # redis = cache
        ser = serializer.FindPasswordSerializer(data=request.data,context={'redis':redis})
        if ser.is_valid():
            return ApiResponse(data=ser.data.get('username'))
        return ApiResponse(code=104,msg='修改密码失败',data=ser.errors)




#学生获取某个学期某个课程的课程表
class CourseDetailView(ViewSet):
    @action(methods=['get'], detail=False)
    def semestercourse(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role==4:
            #获取专业
            profession = models.Profession.objects.filter(stuclass__user=user).first()
            #从缓存中获取数据
            semestercourse = cache.get(othersettings.SEMESTERCOURSE)
            if semestercourse:
                #缓存中有数据就返回缓存中的数据
                return ApiResponse(data=semestercourse)

            semester = models.Semester.objects.all()
            ser_se = serializer.SemesterSerializer(instance=semester,many=True)
            dic={}
            for seme in semester:
                cour = models.Course.objects.filter(profession=profession,semester=seme)
                ser = serializer.CourseSerializer(instance=cour,many=True)
                dic[seme.semestername]={'semester_id':seme.id,'course':ser.data,}
            #将数据缓存到cache中，10分钟有效
            cache.set(othersettings.SEMESTERCOURSE,dic)
            return ApiResponse(data=dic)
        else:
            return ApiResponse(msg='只能学生进行操作')

    @action(methods=['get'],detail=False)
    def detailcourse(self,request,*args,**kwargs):
        #拿到学期id和课程id
        semester_id = request.query_params.get('semester_id')
        # course_id = request.query_params.get('course_id')
        user_id = request.auth.get('id')
        user_obj = models.User.objects.get(id=user_id)
        if not semester_id:
            return ApiResponse(code=104,msg='失败',data={'error':'未携带正常数据'})
        if user_obj.role==4:
            #学生查看
            stuclass = models.stuClass.objects.get(id=user_obj.stuclass.id)
            course = models.Curriculum.objects.filter(stuclass=stuclass,semester_id=semester_id).order_by('course')
            ser = serializer.ShowCurriSerializer(instance=course,many=True)
            return ApiResponse(data=ser.data)
        else:
            return ApiResponse(code=104,msg='只能学生操作')
        # 修改个人信息
    @action(methods=['post'], detail=False)
    def changemyself(self, request, *args, **kwargs):
        ser = serializer.ChangeSelfServerializer(data=request.data, context={'request': request})
        if ser.is_valid():
            user = models.User.objects.filter(id=request.auth.get('id')).update(**request.data)
            return ApiResponse(data=ser.data)
        return ApiResponse(code=104, msg='修改信息失败', data={'error': ser.errors})

#用来操作数据库中课程成绩是否通过，如果课程成绩小于60就设置is_pass=False
class OpelationMysqlView(ViewSet):
    @action(methods=['get'],detail=False)
    def setispass(self,request,*args,**kwargs):
        eles = models.Election.objects.all()
        for ele in eles:
            if float(ele.score)<60:
                ele.is_pass=False
                ele.save()
        return ApiResponse()

class AdminCreateView(ViewSet):
    #拿到学院和专业的关系，学期情况用来为创建课程准备
    @action(methods=['get'],detail=False)
    def colprofession(self,request,*args,**kwargs):
        college = models.College.objects.all()
        lis=[]
        year = time.localtime().tm_year
        y1=str(year-1)
        y2=str(year+1)
        y0=str(year)
        semester = models.Semester.objects.filter(Q(semestername__startswith=y0)|Q(semestername__startswith=y1)|Q(semestername__startswith=y2))
        ser_se = serializer.SemesterSerializer(instance=semester,many=True)
        dic={'semester':ser_se.data}
        for col in college:
            professions = models.Profession.objects.filter(college=col)
            ser = serializer.ProfessionSerializer(instance=professions,many=True)
            lis.append({col.collegename:ser.data})
        dic['profession']=lis
        return ApiResponse(data=dic)
    #课程的创建，选修和必修课，需要外键，专业id、学期id
    @action(methods=['post'], detail=False)
    def createcourse(self, request, *args, **kwargs):
      ser =serializer.CourseSerializer(data=request.data)
      if ser.is_valid():
        return ApiResponse(data=ser.data)
      return ApiResponse(msg='验证不通过',data=ser.errors,code=104)
#老师选课功能
class TeaChoiceCourseView(ViewSet):
    #老师创建选修课
    @action(methods=['post'],detail=False)
    def crechoicecourse(self,request,*args,**kwargs):
        user_id = request.auth.get('id')
        user =models.User.objects.get(id=user_id)
        request.data['college']=1
        request.data['teacher']=1
        request.data['is_pass']=1
        request.data['can_choice']=True
        request.data['is_show']=False
        if user.role==3:
            ser = serializer.ChoiceCourseServerializer(data=request.data)
            if ser.is_valid():
                college = models.College.objects.filter(profession__teaprofession__teacher_id=user_id).first()
                request.data.pop('college')
                request.data.pop('teacher')
                semster_id=request.data.pop('semster')
                models.ChoiceCourse.objects.create(**request.data,teacher_id=user_id,college=college,semster_id=semster_id)
                return ApiResponse(data=ser.data)
            return ApiResponse(code=104,msg='验证不通过',errors=ser.errors)
        return ApiResponse(code=104,msg='只有老师才能创建选修课')
    #老师查看选修课的审核情况，根据学期查看
    @action(methods=['post'],detail=False)
    def tealookresult(self,request,*args,**kwargs):
        '''
        :param request:
        :param args:
        :param kwargs:  semester_id和is_pass
        :return:
        '''
        semester_id=request.data.get('semester_id')
        #查看类型：未审核1、已经通过2、未通过3
        choice = request.data.get('is_pass')
        if choice and semester_id:
            teacourse=models.ChoiceCourse.objects.filter(semster_id=semester_id,is_pass=choice)
            ser = serializer.ChoiceCourseServerializer(instance=teacourse,many=True)
            return ApiResponse(data=ser.data)
        return ApiResponse(code=104,msg='携带数据错误')
    #删除申请的选修课：只能删除未审核和审核失败的课程
    @action(methods=['get'],detail=False)
    def delcourse(self,request,*args,**kwargs):
        '''
        :param request:
        :param args:
        :param kwargs: pk='选修课的id'
        :return:
        '''
        course_id= request.query_params.get('pk')
        if not  course_id:
            return ApiResponse(code=104,msg='没有携带数据')
        try:
            course = models.ChoiceCourse.objects.get(id=course_id,teacher_id=request.auth.get('id'))

            if course.is_pass in [1, 3]:
                #删除课程
                models.ChoiceCourse.objects.get(id=course_id).delete()
                return ApiResponse(msg='删除成功')
            return ApiResponse(code=104, msg='已经通过的课程不能删除')
        except :
            return ApiResponse(code=104,msg='该课程非你申请的课程，不能操作',se=request.auth.get('id'),cour=course_id)

    #修改为审核或审核不通过的选课申请
    @action(methods=['post'],detail=False)
    def editcourse(self,request,*args,**kwargs):
        '''
        :param request:
        :param args:
        :param kwargs: pk='选修课申请的id' 选修课id ，只修改为未审核的。
        "credit": 3,  学分
        "studytime": 48, 课时
        "students": 40,  学生人数
        :return:
        '''
        course_id = request.data.get('pk')
        credit = request.data.get('credit')
        studytime = request.data.get('studytime')
        students = request.data.get('students')
        if credit and students and studytime and course_id:
            try:
                course=models.ChoiceCourse.objects.get(id=course_id,teacher_id=request.auth.get('id'))
                if course.is_pass==2:
                    return ApiResponse(code=104,msg='已经通过的课程，不能进行修改。')
                course.credit=credit
                course.studytime=studytime
                course.students=students
                course.why='' #不通过的原因置空
                course.is_pass=1
                course.save()
                return ApiResponse(msg='修改成功')
            except:
                return ApiResponse(code=104,msg='该课程不是你申请的，不能操作')
        return ApiResponse(code=104, msg='少携带了部分数据')
#学生选课功能
class StuChoiceCourseView(ViewSet):
    #查看当前学期可以选的课程
    @action(methods=['get'],detail=False)
    def stushowcourse(self,request,*args,**kwargs):
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role !=4:
            return ApiResponse(code=104,msg='非学生不能选修课程')
        #获取当前学期。
        semestername=get_semester()
        #拿到学院
        college = models.College.objects.filter(profession__stuclass__user=user).first()
        #拿到当前学期可以选择的选修课列表
        course = models.ChoiceCourse.objects.filter(semster__semestername=semestername,college=college,is_show=False,is_pass=2) #审核通过
        #is_show用来控制选修课的开放
        if course:
            ser = serializer.ChoiceCourseServerializer(instance=course,many=True)
            return ApiResponse(data=ser.data)
        return ApiResponse(code=104,msg='选修还没有开始')
    #学生进行选修【未测试】
    @action(methods=['get'],detail=False)
    def stuchoicecourse(self,request,*args,**kwargs):
        #拿到课程id
        course_id = request.query_params.get('pk')
        course = models.ChoiceCourse.objects.filter(can_choice=True,is_show=False,id=course_id,is_pass=2)
        if course:
            #在学生选课表中记录,
            try:
                models.StudentChoiceCourse.objects.get(course_id=course_id,student_id=request.auth.get('id'))
                return ApiResponse(code=104,msg='已经选过了，不能再选择')
            except:
                models.StudentChoiceCourse.objects.create(course_id=course_id, student_id=request.auth.get('id'))
                #给课程的已选人数+1
                course.update(new_count=F('new_count')+1)
                cou = models.ChoiceCourse.objects.get(id=course_id)
                if cou.new_count>=cou.students:
                    cou.can_choice=False
                    cou.save()
                return ApiResponse(msg='选课成功')
        else:
            return ApiResponse(code=104,msg='选修可能未开始或课程已经满额或无此课程')
    #学生查看自己的选修课
    @action(methods=['get'],detail=False)
    def showchoicecourse(self,request,*args,**kwargs):
        #拿到学期id进行查看
        semester_id = request.query_params.get('pk')
        #用户id
        user_id = request.auth.get('id')
        if not semester_id or request.user[:3]!='312':
            return ApiResponse(code=104,msg='学期id没有携带或非学生操作')
        course=models.StudentChoiceCourse.objects.filter(course__semster_id=semester_id,student_id=user_id)
        ser = serializer.ChoiceCourseShowServerializer(instance=course,many=True)
        return ApiResponse(data=ser.data)

    #学生退出选课，删除选课
    @action(methods=['get'],detail=False)
    def delstucourse(self,request,*args,**kwargs):
        #退出当前学期的选课情况了
        user_id =request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role!=4:
            return ApiResponse(code=104,msg='非学生，无法操作')
        #拿到当前的选课id
        stucourse_id=request.query_params.get('pk')
        if not stucourse_id:
            return ApiResponse(code=104,msg='未携带课程id')
        semestername = get_semester()
        try:
            cour= models.StudentChoiceCourse.objects.get(course__semster__semestername=semestername,id=stucourse_id,student_id=user_id).delete()
            return ApiResponse(msg='删除成功',data=cour)
        except:
            return ApiResponse(code=104,msg='删除失败，无法查询到记录')
#管理员处理选修课功能
class AdminChoiceCoureseView(ViewSet):
    #管理员查看老师发布的课程申请,拿到要申请类型：未审核1，审核通过2，审核失败3
    @action(methods=['get'],detail=False)
    def checkapply(self,request,*args,**kwargs):
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role not in [1,2,3,4]:
            return ApiResponse(code=104,msg='没有权限操作')
        #申请类型：未审核1，审核通过2，审核失败3
        is_pass = request.query_params.get('is_pass')
        #学院id
        college_id = request.query_params.get('college_id')
        course = models.ChoiceCourse.objects.filter(is_pass=is_pass,college_id=college_id)
        ser =serializer.ChoiceCourseServerializer(instance=course,many=True)
        return ApiResponse(data=ser.data)
    #管理员对申请进行审核，输入is_pass = 2或3代表审核通过和不通过
    @action(methods=['post'],detail=False)
    def editispass(self,request,*args,**kwargs):
        why = request.data.get('why','')
        is_pass = request.data.get('is_pass')
        course_id = request.data.get('course_id')
        user= models.User.objects.get(id = request.auth.get('id'))
        if user.role not in [1,2,3,4]:
            return ApiResponse(code=104,msg='没有权限操作')
        if not is_pass or not course_id:
            return ApiResponse(code=104,msg='没有携带审批结果或审核课程id')
        if is_pass not in[2,3]:
            return ApiResponse(code=104,msg='审核失败',data={'error':"审核的结果有问题。"})
        try:
            course=models.ChoiceCourse.objects.get(id=course_id)
            course.why=why
            course.is_pass=is_pass
            course.save()
            return ApiResponse(data={'course':course.coursename,'is_pass':course.get_is_pass_display()})
        except:
            return ApiResponse(code=104,msg='失败',data={'error':'携带课程id有误'})
    #展示学院和学期的数据
    @action(methods=['get'],detail=False)
    def semestercollege(self,request,*args,**kwargs):
        semester = models.Semester.objects.all()
        college = models.College.objects.all()
        ser_seme = serializer.SemesterSerializer(instance=semester,many=True)
        ser_col = serializer.CollegeSerializer(instance=college,many=True)
        return ApiResponse(data={'college':ser_col.data,'semester':ser_seme.data})
    # 展示某个学期某个学院审核通过的选修课,获取到选修课程的id
    @action(methods=['get'],detail=False)
    def showpasscourse(self,request,*args,**kwargs):
        '''
        :param request:
        :param args:
        :param kwargs:  college:id,semester:id
        :return:
        '''
        college_id = request.query_params.get('college_id')
        semester_id = request.query_params.get('semester_id')
        if not college_id or not semester_id:
            return ApiResponse(code=104,msg='缺少部分必要携带数据')
        course = models.ChoiceCourse.objects.filter(semster_id=semester_id,college_id=college_id,is_pass=2)
        ser = serializer.ChoiceCourseServerializer(instance=course,many=True)
        return ApiResponse(data=ser.data)

    #给选修课程创建具体的上课时间。
    @action(methods=['post'],detail=False)
    def addetailcorse(self,request,*args,**kwargs):
        '''
        :param kwargs:
        {"location","weeks":上课周次，"section":上课节数，”course_id“:课程id，”days“:星期}
        '''
        location = request.data.get('location')
        weeks = request.data.get('weeks')
        section = request.data.get('section')
        course = request.data.get('course_id')
        days = request.data.get('days')
        if not location or not weeks or not section or not course or not days:
            return ApiResponse(code=104,msg='缺少部分数据')
        try:
            coursestudy = models.ChoiceCourseStudy.objects.get(**request.data)
            return ApiResponse(code=104,msg='数据已经存在了。')
        except:
            try:
                study=models.ChoiceCourseStudy.objects.create(**request.data)
                return ApiResponse(msg='创建成功')
            except:
                return ApiResponse(code=104,msg='携带数据有误')
    #根据学院学期获取选课的具体上课时间和地点
    @action(methods=['get'],detail=False)
    def showdetailchoicecourse(self,request,*args,**kwargs):
        '''
        :param kwargs:  semester_id:学期id，college_id:学院id
        :return:
        '''
        semester_id = request.query_params.get('semester_id')
        college_id = request.query_params.get('college_id')
        if not semester_id or not college_id:
            return ApiResponse(code=104,msg='缺少部分携带数据')
        course = models.ChoiceCourseStudy.objects.filter(course__is_pass=2,course__semster_id=semester_id,course__college_id=college_id).order_by('course')
        ser =serializer.StuChoiceCourseView(instance=course,many=True)
        return ApiResponse(data=ser.data)
#生成excel表格的视图类

class ExportExcelTableView(ViewSet):
    authentication_classes = [MyJWTAuthentication]
    #生成一个班级的学生信息的excel表格
    @action(methods=['get'],detail=False)
    def outtudents(self,request,*args,**kwargs):
        stuclass = request.query_params.get('class_id')
        if not stuclass:
            return ApiResponse(code=104,msg='生成文件失败',data={'error':'未携带班级id'})
        try:
            stu_class=models.stuClass.objects.get(id=stuclass)
        except :
            return ApiResponse(code=104,msg='无找到对应班级信息')
        this_user = models.User.objects.get(id=request.auth.get('id'))
        if this_user.role ==4:
            return ApiResponse(code=104,msg='学生没有权限生成班级信息')
        users = models.User.objects.filter(stuclass_id=stuclass,role=4)
        #对学生信息进行序列化
        ser = serializer.StudentsExcelServializer(instance=users,many=True)
        #新建一个工作簿
        wb = Workbook()
        #新建一个工作表
        ws = wb.create_sheet('students',0)
        ws.append(['姓名','学号','手机号码','邮箱','身份证','班级','性别'])
        for dic in ser.data:
            ws.append(
                [dic.get('name'),dic.get('username'),
                 dic.get('telephone'),dic.get('email'),
                 dic.get('sid'),dic.get('class_name'),
                 dic.get('sex_name')]
            )
        #文件名:班级+老师职工号
        name = f'{stu_class.classon}-{request.user}.xlsx'
        # 这个是media文件夹下的students_excels文件夹路径，保存学生消息的excel表
        PATH = os.path.join(settings.MEDIA_ROOT,'students_excels',name)
        wb.save(PATH)
        #将生成文件的名字写到数据库表中
        try:
            db_file=models.StudentMessageExcel.objects.update_or_create(filename=name,user_id=request.auth.get('id'))
            return ApiResponse(msg='生成班级文件成功',data={'文件名':name})
        except:
            return ApiResponse(code='104',msg='创建文件失败')
    #生成某个班级某个学期上，所有的课程的成绩。每课占一个工作表
    @action(methods=['post'],detail=False)
    def creditexcel(self,request,*args,**kwargs):
        semetser = request.data.get('semester')
        stuclass = request.data.get('stuclass')
        profession = request.data.get('profession')
        user =models.User.objects.get(id=request.auth.get('id'))
        if user.role==4:
            return ApiResponse(code=104,msg='学生没有权限操作')
        try:
            sem = models.Semester.objects.get(id=semetser)
            stu = models.stuClass.objects.get(id=stuclass)
            course = models.Course.objects.filter(profession_id=profession, semester_id=semetser)
            if not course:
                return ApiResponse(code=104,msg='失败',error='本学期该专业没有课程')
            filename = f'{sem.semestername}-{stu.classon}-{request.user}.xlsx'
        except:
            return ApiResponse(code=104, msg='携带的数据有问题')
        #拿到课程数，几个查课程创建几个工作表
        course_ser = serializer.CourseSerializer(instance=course,many=True)
        #创建一个工作簿
        wb = Workbook()
        ws_lis=[]
        #生成与课程数一样的工作表
        for i,cour in enumerate( course_ser.data,0):
            ws=wb.create_sheet(title=cour.get('coursename'),index=i)
            ws.append(['课程','分数','姓名','学号','班级','学期','及格'])
            course_credit = models.Election.objects.filter(course_id=cour['id'],stuclass_id=stuclass)
            ser = serializer.ExcelCreditServerializer(instance=course_credit,many=True)
            for dic in ser.data:
                ws.append([
                    dic.get('coursename'), float(dic.get('score')),
                    dic.get('name'),dic.get('username'),
                    dic.get('get_class'), dic.get('semester'),
                    dic.get('is_pass')
                ])
        #拿到media下credit_excel的路径，将工作簿保存到此路径
        PATH=os.path.join(settings.MEDIA_ROOT,'credit_excels',filename)
        wb.save(PATH)

        try:
            db_file=models.StudentCreditExcel.objects.get_or_create(filename=filename,user_id=request.auth.get('id'))
            return ApiResponse(msg='生成班级课程成绩文件成功',data={'文件名':filename})
        except:
            return ApiResponse(code='104',msg='创建文件失败')

#老师，管理员查看自己生成的班级excel表格,文件所在的路径也在其中，直接点击路径就可以下载文件
class TeaShowStuMsg(GenericViewSet,ListModelMixin,DestroyModelMixin):
    queryset = models.StudentMessageExcel.objects.all()
    serializer_class = serializer.TeaShowStuMsgServerializer
    #重写list方法
    def list(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role==4:
            return ApiResponse(code=104,msg='学生没有权限操作')
        queryset = models.StudentMessageExcel.objects.filter(user_id=user_id)
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(data=serializer.data)
    # 删除的视图函数
    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, *args, **kwargs)
        if response:
            return ApiResponse(msg='删除文件成功')
class TeaShowStuCredit(GenericViewSet,ListModelMixin,DestroyModelMixin):
    queryset = models.StudentCreditExcel.objects.all()
    serializer_class = serializer.TeaShowCreditServerializer
    #重写list方法
    def list(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role==4:
            return ApiResponse(code=104,msg='学生没有权限操作')
        queryset = models.StudentCreditExcel.objects.filter(user_id=user_id)
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(data=serializer.data)
    #删除的视图函数
    def destroy(self, request, *args, **kwargs):
        response = super().destroy(request, *args, **kwargs)
        if response:
            return ApiResponse(msg='删除文件成功')

#奖学金评定
class Scholarship(ViewSet):
    authentication_classes = [MyJWTAuthentication]
    @action(methods=['get'],detail=False)
    def showprivacredit(self,request):
        user = models.User.objects.get(id=request.auth.get('id'))
        if user.role==4:
            return ApiResponse(code=104,msg='学生没有权限操作')
        profession_id = request.query_params.get('profession_id')
        semester_id = request.query_params.get('semester_id')
        if not profession_id or not semester_id:
            return ApiResponse(code=104,msg='没有携带专业id')
        #获取当前学期
        try:
            semestername = models.Semester.objects.get(id=semester_id).semestername
        except:
            return ApiResponse(code=104,msg='没有查到相关数据')
        credi = models.Election.objects.filter(stuclass__profession_id=profession_id,course__semester__semestername=semestername).order_by('course')
        if not credi:
            return ApiResponse(code=104,msg='查询不到数据',data={'why':'此学期下的数据查询不到，请咨询管理员'})
        ser = serializer.ExcelCreditServerializer(instance=credi,many=True)
        # return ApiResponse(data=ser.data)
        try:
            profession = models.Profession.objects.get(id=profession_id)
        except:
            return ApiResponse(code=104,msg='无查询到相关数据')
        courses = models.Course.objects.filter(profession=profession,semester__semestername=semestername)
        course_ser = serializer.CourseSerializer(instance=courses,many=True)
        #新建一个工作簿
        wb = Workbook()
        ws = wb.create_sheet(title=profession.pname,index=0)
        lis=[]
        for cou in courses:
            lis.append(cou.coursename)
        ws.append(['姓名', '学号','班级','学期', *lis])
        pro_user = models.User.objects.filter(stuclass__profession=profession,role=4)
        user_lis=[]
        for user in pro_user:
            dic={}
            for i, data in enumerate( ser.data,0):
                if i==0:
                    dic['score']=[]
                flag=0
                if user.username==data.get('username'):
                    if flag==0:
                        dic['username']=data.get('username')
                        dic['name']=data.get('name')
                        dic['get_class']=data.get('get_class')
                        dic['semester']=data.get('semester')
                        flag=1
                    #将成绩写到列表中
                    dic['score'].append(float(data.get('score')))
            user_lis.append(dic)
            ws.append([
                dic.get('name'),dic.get('username'),
                dic.get('get_class'),dic.get('semester'),
                *dic.get('score')
            ])
        filename = f'{profession.pname}-{semestername}-{request.user}.xlsx'
        PATH = os.path.join(settings.MEDIA_ROOT, 'profession_cred_excel',filename)
        wb.save(PATH)
        try:
            models.ProfessionCreditExcel.objects.update_or_create(user_id=request.auth.get('id'),filename=filename)
            return ApiResponse(data={'文件名':filename})
        except:
            return ApiResponse(code=104,msg='未知错误')

#查看自己生成的学期专业课程成绩表
class TeaShowProfessionCredit(GenericViewSet,ListModelMixin,DestroyModelMixin):
    queryset = models.ProfessionCreditExcel.objects.all()
    serializer_class = serializer.ProfessionCreditServerializer
    #重写list方法
    def list(self, request, *args, **kwargs):
        user_id = request.auth.get('id')
        user = models.User.objects.get(id=user_id)
        if user.role==4:
            return ApiResponse(code=104,msg='学生没有权限操作')
        queryset = models.ProfessionCreditExcel.objects.filter(user_id=user_id)
        serializer = self.get_serializer(queryset, many=True)
        return ApiResponse(data=serializer.data)

    def destroy(self, request, *args, **kwargs):
        def destroy(self, request, *args, **kwargs):
            response = super().destroy(request, *args, **kwargs)
            if response:
                return ApiResponse(msg='删除文件成功')
import openpyxl
class TestExcelView(ViewSet):
    authentication_classes = []
    permission_classes = []
    throttle_classes = []
    @action(methods=['get'],detail=False)
    def testexcel(self,request):
        path=os.path.join(settings.MEDIA_ROOT,'students_excels','test.xlsx')
        wb = openpyxl.load_workbook(path)
        ws = wb.active
        max_row = ws.max_row
        max_column = ws.max_column
        all_lis=[]
        lis=[]
        for row in range(1,max_row+1):
            dic={}
            for column in range(1,max_column+1) :
                if row==1:
                    #将首行的东西加到列表中
                    lis.append(ws.cell(row,column).value)
                    continue
                #将行首标题作为的key，其余行对应列作为value，拿到dict，一行就一个dict
                dic.setdefault(lis[column-1],ws.cell(row,column).value)
            if row>1:
                #首行的dict就是空，不需要加入
                all_lis.append(dic)
        try:
            # for user_dic in all_lis:
            #     models.User.objects.create_user(**user_dic)
            return ApiResponse(msg='创建用户成功',leng=len(all_lis),data=all_lis)
        except:
            return ApiResponse(data={'erroe':'excel文件有问题，先检查文件格式'})










